#include <stdio.h>
#include <memory.h>
#include <cmath>
#include <utility>
#if 0
#include "search.hpp"
#else
#include <queue>

#define NODE_VISITING   1
#define NODE_EXPANDED   2
#define NODE_SKIPPED    3

template <class T>
struct ignore_progress
{
    void operator()(int /* reason */, const T & /* state */) { }
};

template <class T>
struct search_stat
{
    size_t num_expanded;
    size_t num_visited;
    size_t num_skipped;
    void operator()(int reason, const T & /* state */)
    {
        switch (reason)
        {
        case NODE_VISITING: ++num_visited; break;
        case NODE_EXPANDED: ++num_expanded; break;
        case NODE_SKIPPED:  ++num_skipped; break;
        }
    }
};

template <class T>
struct astar_node
{
    T state;
    int g;      /* current cost */
    int f;      /* current cost + estimated remaining cost */

    astar_node(const T &_state, int current_cost, int estimated_cost) 
        : state(_state), g(current_cost), f(current_cost + estimated_cost)
    { }

    /* Returns true if this node is less promising than 'other'. */
    bool operator < (const astar_node<T> &other) const
    {
        return (f > other.f) || (f == other.f && g < other.g);
    }
};

template <class T, class Expander, class StateSet, class Heuristic, 
          class Progress>
int astar_search(
    const T &start,     /* Start state. */
    const T &goal,      /* Goal state. */
    StateSet &visited,  /* Set of states to be excluded from the search. */
    Expander expand,    /* Function that expands the children of a state. */
    Heuristic h,        /* Heuristic function. */
    Progress &report)   /* Search progress callback. */
{
    typedef astar_node<T> Node;
    std::priority_queue<Node> q;
    q.push(Node(start, 0, h(start)));
    while (!q.empty())
    {
        Node node = q.top();
        q.pop();

        const T &state = node.state;
        if (!visited.insert(state).second) /* already exists */
        {
            report(NODE_SKIPPED, state);
            continue;
        }

        report(NODE_VISITING, state);
        if (state == goal)
            return node.f;

        T child;
        for (size_t k = 0; expand(state, k, &child); k++)
        {
            if (visited.count(child) == 0)
            {
                q.push(Node(child, node.g + 1, h(child)));
                report(NODE_EXPANDED, child);
            }
        }
    }
    return -1;
}
#endif

#define XMIN    -500
#define XMAX    500
#define YMIN    -500
#define YMAX    500

typedef short coor_t;

struct Location
{
    coor_t x, y;
    Location() { }
    Location(coor_t _x, coor_t _y) : x(_x), y(_y) { }
    bool operator==(const Location &other) const 
    {
        return x == other.x && y == other.y;
    }
};

static Location target;

static int estimate_length(const Location &loc)
{
    return std::abs(loc.x - target.x) + std::abs(loc.y - target.y);
}

static bool expand_child(const Location &loc, size_t k, Location *child)
{
    static const coor_t dir[4][2] = { {-1, 0}, {0, 1}, {1, 0}, {0, -1} };
    if (k >= 4)
        return false;

    coor_t x = loc.x + dir[k][0], y = loc.y + dir[k][1];
    if (x >= XMIN && x <= XMAX && y >= YMIN && y <= YMAX)
    {
        child->x = x;
        child->y = y;
        return true;
    }
    return false;
}

struct location_set
{
    bool visited[1024][1024];

    void clear() { memset(visited, 0, sizeof(visited)); }

    size_t count(const Location &loc) const 
    {
        return visited[loc.x - XMIN][loc.y - YMIN];
    }

    std::pair<int,bool> insert(const Location &loc)
    {
        bool exists = visited[loc.x - XMIN][loc.y - YMIN];
        visited[loc.x - XMIN][loc.y - YMIN] = true;
        return std::pair<int,bool>(0, !exists);
    }

    size_t erase(const Location &loc)
    {
        bool exists = visited[loc.x - XMIN][loc.y - YMIN];
        visited[loc.x - XMIN][loc.y - YMIN] = false;
        return exists;
    }
};

static location_set visited;

#ifdef _DEBUG
static void display()
{
    static char buffer[YMAX-YMIN+1][XMAX-XMIN+2];
    memset(buffer, '.', sizeof(buffer));

    int xmin = std::min(0, (int)target.x), xmax = std::max(0, (int)target.x);
    int ymin = std::min(0, (int)target.y), ymax = std::max(0, (int)target.y);
    for (int y = YMIN; y <= YMAX; y++)
    {
        for (int x = XMIN; x <= XMAX; x++)
        {
            if (visited.visited[x-XMIN][y-YMIN])
            {
                xmin = std::min(xmin, x);
                xmax = std::max(xmax, x);
                ymin = std::min(ymin, y);
                ymax = std::max(ymax, y);
                buffer[y-YMIN][x-XMIN] = 'x';
            }
        }
    }
    buffer[0-YMIN][0-XMIN] = 'S';
    buffer[target.y-YMIN][target.x-XMIN] = 'T';

    if (ymax - ymin > 75 || xmax - xmin > 75)
    {
        printf("Too big.\n");
        return;
    }
    for (int y = ymin; y <= ymax; y++)
    {
        buffer[y-YMIN][xmax-XMIN+1] = '\0';
        printf("%s\n", &buffer[y-YMIN][xmin-XMIN]);
    }
}
#endif

int main()
{
    int num_mud, x, y;
    while (scanf("%d %d %d", &x, &y, &num_mud) == 3)
    {
        target.x = (coor_t)x;
        target.y = (coor_t)y;
        Location start(0, 0);

        visited.clear();
        for (int i = 0; i < num_mud; i++)
        {
            scanf("%d %d", &x, &y);
            visited.insert(Location((coor_t)x, (coor_t)y));
        }
        visited.erase(start);
        visited.erase(target);

#ifdef _DEBUG
        display();
        search_stat<Location> stat = { 0 };
        int length = astar_search(start, target, visited,
                                  expand_child, estimate_length, stat);
        printf("Shortest: %d, #Visited: %d, #Expanded: %d, #Skipped: %d\n\n",
            length, stat.num_visited, stat.num_expanded, stat.num_skipped);
#else
        ignore_progress<Location> progress;
        int length = astar_search(start, target, visited,
                                  expand_child, estimate_length, progress);
        printf("%d\n", length);
#endif
    }
    return 0;
}
